package com.ali.gts.servlet.dao.impl;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


import com.ali.gts.servlet.util.JDBCUtils;

import javafx.beans.binding.ObjectExpression;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;


/*
 * 所有Dao实现类的基类
	 进行的操作:DML DQL
	 它要借用哪些类去完成功能?
	 1. JDBCUtils
	 2. dbutils.jar
		 QueryRunner
		 update(...)  //DML
		 query(....)  //DQL
		 ResultSetHandler(接口)
		 BeanHandler  -->返回一个对象
		 BeanListHandler --->返回一个对象的集合
 */
public abstract class BaseDao<T> {

	private QueryRunner runner = new QueryRunner();
	private Class<T> beanType;

	public BaseDao() {
		//BaseDao<User>
		ParameterizedTypeImpl genericSuperclass = (ParameterizedTypeImpl) this.getClass().getGenericSuperclass();
		//User的class对象
		beanType = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
	}

	/**
	 * 对表数据进行增删改操作 CUD DML
	 * @param sql
	 * @param params
	 */
	public int update(String sql, Object... params) {
		Connection conn = null;

		try {
			conn = JDBCUtils.getConnection();
			return runner.update(conn, sql, params);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw  new RuntimeException(e);

		}
		//这里在JDBCUtils使用了ThreadLocal后就注释掉了。
//		finally {
//			JDBCUtils.releaseConn(conn);
//		}
	}

	/**
	 * 查询得到一个对象
	 * @param sql
	 * @param params
	 * @return
	 */
	public T query(String sql, Object... params) {
		T t = null;

		Connection conn = null;

		try {
			conn = JDBCUtils.getConnection();
			t = runner.query(conn, sql, new BeanHandler<T>(beanType), params);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw  new RuntimeException(e);

		}
		//这里在JDBCUtils使用了ThreadLocal后就注释掉了。

//		finally {
//			JDBCUtils.releaseConn(conn);
//		}

		return t;
	}

	/**
	 * 查询得到一个对象的集合
	 * @param sql
	 * @param params
	 * @return
	 */
	public List<T> queryForList(String sql, Object... params) {
		List<T> list = new ArrayList<>();

		Connection conn = null;

		try {
			conn = JDBCUtils.getConnection();
			list = runner.query(conn, sql, new BeanListHandler<T>(beanType),
					params);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw  new RuntimeException(e);
		}
		//这里在JDBCUtils使用了ThreadLocal后就注释掉了。
//		finally {
//			JDBCUtils.releaseConn(conn);
//		}

		return list;
	}

	/**
	 * 执行返回一行一列的sql语句
	 * @return
	 */
	public Object queryForSingleValue(String sql,Object... args){
		Connection conn = null;
		try{
			conn = JDBCUtils.getConnection();
			return runner.query(conn,sql,new ScalarHandler(),args);
		}catch (Exception e){
			e.printStackTrace();
		}
		//这里在JDBCUtils使用了ThreadLocal后就注释掉了。
//		finally {
//			JDBCUtils.releaseConn(conn);
//		}
		return null;

	}

}
